package cn.anecansaitin.jep.parser.ast.node.expression;

import cn.anecansaitin.jep.Token;
import cn.anecansaitin.jep.parser.ast.node.NodeCreationResult;
import cn.anecansaitin.jep.types.TypeInfo;

public final class Unary extends Expression {
    private final Token operator;
    private final Expression expression;
    private final boolean postfix;

    private Unary(Token operator, Expression expression, boolean postfix, TypeInfo resultType, int line, int column) {
        super(resultType, line, column);
        this.operator = operator;
        this.expression = expression;
        this.postfix = postfix;
    }

    public Token operator() {
        return operator;
    }

    public Expression expression() {
        return expression;
    }

    public boolean postfix() {
        return postfix;
    }

    public static NodeCreationResult<Unary> create(Token operator, Expression expression, boolean postfix, int line, int column) {
        return switch (operator.type()) {
            case NOT -> {
                if (expression.resultType() == TypeInfo.BOOLEAN) {
                    yield NodeCreationResult.success(new Unary(operator, expression, postfix, TypeInfo.BOOLEAN, line, column));
                } else {
                    yield NodeCreationResult.fail(operator + "不能用于" + expression.resultType());
                }
            }
            case UNARY_PLUS, UNARY_MINUS, BIT_NOT -> switch (expression.resultType()) {
                case INT, CHAR -> NodeCreationResult.success(new Unary(operator, expression, postfix, TypeInfo.INT, line, column));
                case LONG -> NodeCreationResult.success(new Unary(operator, expression, postfix, TypeInfo.LONG, line, column));
                default -> NodeCreationResult.fail(operator + "不能用于" + expression.resultType());
            };
            default -> NodeCreationResult.fail("未知的运算符 " + operator);
        };
    }
}